package com.wv.api.service.impl;

import cn.hutool.core.lang.Snowflake;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.RandomUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.github.pagehelper.PageHelper;
import com.wv.api.mapper.SysRoleDao;
import com.wv.api.mapper.SysUserDao;
import com.wv.api.mapper.SysUserRoleDao;
import com.wv.api.service.ISysUserService;
import com.wv.common.exception.WVException;
import com.wv.common.result.HttpCodeEnum;
import com.wv.common.result.PageResponseResult;
import com.wv.common.result.Result;
import com.wv.model.system.SysUserRole;
import com.wv.model.system.condition.SysUserCondition;
import com.wv.model.system.SysUser;
import com.wv.utils.MD5EncryptionUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;
import java.util.stream.Collectors;

@Service
public class SysUserServiceImpl extends ServiceImpl<SysUserDao,SysUser> implements ISysUserService {

    @Autowired
    private SysUserDao sysUserDao;

    @Autowired
    private SysUserRoleDao sysUserRoleDao;

    @Override
    public PageResponseResult getUser(SysUserCondition sysUserCondition) {
        sysUserCondition.checkParam();
        PageHelper.startPage(sysUserCondition.getPage(), sysUserCondition.getSize());
        PageResponseResult build = PageResponseResult.builder()
                .total(sysUserDao.selectUserCount(sysUserCondition))
                .currentPage(sysUserCondition.getPage())
                .build();
        List<SysUser> collect = sysUserDao.selectLeftJoin(sysUserCondition).stream().peek(sysUser -> {
            LambdaQueryWrapper<SysUserRole> wrapper = new LambdaQueryWrapper<>();
            wrapper.eq(SysUserRole::getUserId, sysUser.getId());
            List<String> roles = sysUserRoleDao.selectList(wrapper).stream()
                    .map(SysUserRole::getRoleId)
                    .collect(Collectors.toList());
            sysUser.setRoleIds(roles);
        }).collect(Collectors.toList());
        build.setData(collect);
        return build;
    }

    @Override
    @Transactional
    public Result addUser(SysUser sysUser) {
        //        生成id
        Snowflake snowflake = IdUtil.createSnowflake(1, 1);
        //        生成随机盐
        String salt = MD5EncryptionUtil.RandomSalt();
        //        密码加密
        String encode = MD5EncryptionUtil.EncodeByMd5(sysUser.getPassword(), salt);
        sysUser.setId(snowflake.nextIdStr());
        sysUser.setPassword(encode);
        sysUser.setSalt(salt);
        sysUser.setCreateTime(LocalDateTime.now());
        int i = sysUserDao.insert(sysUser);
        if (i <= 0){
            throw new WVException(HttpCodeEnum.ADD_ERROR);
        }
        int i1 = sysUserRoleDao.batchInsert(sysUser.getId(), sysUser.getRoleIds());
        if (i1 != sysUser.getRoleIds().size()) throw new WVException(HttpCodeEnum.ADD_ERROR);
        return Result.ok();
    }

    @Override
    public Result addUser(List<SysUser> list) {
        List<SysUser> collect = list.stream().peek(sysUser -> {
            //        生成id
            Snowflake snowflake = IdUtil.createSnowflake(1, 2);
            String randomStr = String.valueOf(RandomUtil.randomInt(10000,99999));
            //        生成随机盐
            String salt = MD5EncryptionUtil.RandomSalt();
            //        密码加密
            String encode = MD5EncryptionUtil.EncodeByMd5(sysUser.getPassword(), salt);
            sysUser.setId(snowflake.nextIdStr() + randomStr);
            sysUser.setPassword(encode);
            sysUser.setSalt(salt);
            sysUser.setCreateTime(LocalDateTime.now());
        }).collect(Collectors.toList());
        int i = sysUserDao.insertBatch(collect);
        return i > 0 ? Result.ok() : Result.error(HttpCodeEnum.ADD_ERROR);
    }

    @Override
    @Transactional
    public Result updateUser(SysUser sysUser) {
        sysUser.setUpdateTime(LocalDateTime.now());
        int i = sysUserDao.updateById(sysUser);
        if (i <= 0) throw new WVException(HttpCodeEnum.UPDATE_ERROR);
        LambdaQueryWrapper<SysUserRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUserRole::getUserId,sysUser.getId());
        int i1 = sysUserRoleDao.delete(wrapper);
        if (i1 <= 0) throw new WVException(HttpCodeEnum.UPDATE_ERROR);
        int i2 = sysUserRoleDao.batchInsert(sysUser.getId(), sysUser.getRoleIds());
        if (i2 != sysUser.getRoleIds().size()) throw new WVException(HttpCodeEnum.UPDATE_ERROR);
        return Result.ok();
    }

    @Override
    @Transactional
    public Result deleteUser(String id) {
        LambdaQueryWrapper<SysUserRole> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(SysUserRole::getUserId,id);
        sysUserRoleDao.delete(wrapper);
        int i = sysUserDao.deleteById(id);
        if (i <= 0) throw new WVException(HttpCodeEnum.DElETE_ERROR);
        return Result.ok();
    }

    @Override
    public Result resetPassword(SysUser sysUser) {
        //        生成随机盐
        String salt = MD5EncryptionUtil.RandomSalt();
        //        密码加密
        String encode = MD5EncryptionUtil.EncodeByMd5(sysUser.getPassword(), salt);
        sysUser.setPassword(encode);
        sysUser.setSalt(salt);
        int i = sysUserDao.updateById(sysUser);
        return i > 0 ? Result.ok() : Result.error(HttpCodeEnum.UPDATE_ERROR);
    }

    @Override
    public Result getUserList() {
        return Result.ok(sysUserDao.selectList(null));
    }
}
